﻿Imports System.IO
Imports System.Text

Module Mods

    Class GMod
        Public Name As String
        Public State As CheckState
        Public Line As Integer ' Строка мода в файле

        Sub New(_name As String, _state As CheckState)
            Name = _name
            State = _state
        End Sub
        Sub New(_name As String, _state As CheckState, _line As Integer)
            Name = _name
            State = _state
            Line = _line
        End Sub

        Public Sub SetLine(_line As Integer)
            Line = _line
        End Sub

        Public Overrides Function ToString() As String
            Return String.Format("{0} Line: {1}", Name, Line)
        End Function
    End Class

    Private modsIniFile As String = Nothing
    Private change As Boolean = False

    ' содержимое файла
    Private modsContent As List(Of String)

    ' Список модов
    Private modsList As List(Of GMod) = New List(Of GMod)

    Private avaliableMods As List(Of String) = New List(Of String)

    Private Function ParseLine(line As String) As GMod
        Dim nPos = line.IndexOfAny(New Char() {";"c, "#"c})
        If (nPos <> -1) Then
            line = line.Remove(nPos) ' удаляем коментарий в строке
        End If

        line = line.TrimStart()
        If (line.Length = 0) Then Return Nothing

        nPos = line.IndexOf("="c)
        If (nPos <> -1) Then
            Dim name = line.Substring(0, nPos).Trim()

            Dim state = CheckState.Indeterminate
            Dim modName = Application.StartupPath + "\mods\" + name

            If File.Exists(modName) OrElse Directory.Exists(modName) Then
                state = CheckState.Checked
                Dim value = line.Substring(nPos + 1).Trim()
                If (value = "0") Then state = CheckState.Unchecked
            End If

            Return New GMod(name, state)
        End If

        Return Nothing
    End Function

    Private Function ParseTxtLine(line As String) As GMod
        Dim nPos = line.IndexOfAny(New Char() {";"c, "#"c})
        If (nPos <> -1) Then
            line = line.Remove(nPos) ' удаляем коментарий в строке
        End If

        line = line.TrimStart()
        If (line.Length = 0) Then Return Nothing

        Dim state = CheckState.Indeterminate
        Dim modName = Application.StartupPath + "\mods\" + line

        If File.Exists(modName) OrElse Directory.Exists(modName) Then
            state = CheckState.Checked
        End If

        Return New GMod(line, state)
    End Function

    Friend Sub LoadModsList()
        Dim modsPath As String = Application.StartupPath + "\mods\"
        Dim modsFile As String = modsPath + "mods_order.ini"

        If File.Exists(modsFile) Then
            modsIniFile = "\mods\mods_order.ini"

            modsContent = File.ReadAllLines(modsFile, Encoding.Default).ToList()

            For i As Integer = 0 To modsContent.Count() - 1
                Dim modfile = ParseLine(modsContent.Item(i))
                If (modfile IsNot Nothing) Then
                    modfile.Line = i
                    modsList.Add(modfile)
                End If
            Next
        End If

        'If (modsContent IsNot Nothing) Then
        LoadAutoMods()
        'End If
    End Sub

    Friend Sub LoadAutoMods()
        Dim modsPath As String = Application.StartupPath + "\mods\"

        avaliableMods.Clear()

        'загркузить список модов в лист
        If Directory.Exists(modsPath) Then
            Dim aMods As List(Of String) = Directory.GetFiles(modsPath, "*.dat", SearchOption.TopDirectoryOnly).ToList()
            aMods.AddRange(Directory.GetDirectories(modsPath, "*.dat", SearchOption.TopDirectoryOnly))

            For Each item In aMods
                avaliableMods.Add(Path.GetFileName(item))
            Next
            avaliableMods.Sort()
        End If

        'удалить уже подключенные моды
        For Each m In modsList
            For i = 0 To avaliableMods.Count() - 1
                If (String.Compare(m.Name, avaliableMods.Item(i), True) = 0) Then
                    avaliableMods.RemoveAt(i)
                    Exit For
                End If
            Next
        Next
    End Sub

    Friend Sub SaveModsList()
        If (change = False OrElse modsIniFile Is Nothing) Then Exit Sub
        change = False

        If (modsContent.Count > 0) Then
            For Each _mod In modsList
                Dim state As String = If(_mod.State <> CheckState.Unchecked, "=1", "=0")
                modsContent(_mod.Line) = _mod.Name + state
            Next
        End If
        File.WriteAllLines(Application.StartupPath + modsIniFile, modsContent.ToArray())
    End Sub

    Friend Sub CreateModsFile()
        Dim modsTxtPath As String = Application.StartupPath + "\mods\mods_order.txt"

        If File.Exists(modsTxtPath) Then
            modsContent = File.ReadAllLines(modsTxtPath, Encoding.Default).ToList()

            For i As Integer = 0 To modsContent.Count() - 1
                Dim modfile = ParseTxtLine(modsContent.Item(i))

                If (modfile IsNot Nothing) Then
                    modfile.Line = i
                    modsList.Add(modfile)
                End If
            Next
        Else
            ' добавить весь список
            modsContent = New List(Of String)()
            For Each am In avaliableMods
                modsContent.Add(am + "=1")
                modsList.Add(New GMod(am, CheckState.Checked, modsContent.Count - 1))
            Next
        End If

        change = True
        modsIniFile = "\mods\mods_order.ini"
        SaveModsList()
    End Sub

    Friend Sub OpenModsFile()
        If (modsIniFile IsNot Nothing) Then
            ConfigFile.OpenConfig(modsIniFile)
        End If
    End Sub

    Friend Sub GetOrderModsList(ByRef _items As CheckedListBox.ObjectCollection)
        For Each m In modsList
            _items.Add(m.Name, m.State)
        Next
    End Sub

    Friend Function GetAvaliableMods() As List(Of String)
        Return avaliableMods
    End Function

    Friend Sub ModOrderLineTo(fromIndex As Integer, toIndex As Integer)
        Dim modMove = modsList.Item(fromIndex)
        Dim modMoveTo = modsList.Item(toIndex)

        Dim line = modsContent.Item(modMove.Line)
        modsContent.RemoveAt(modMove.Line)

        modsContent.Insert(modMoveTo.Line, line)
        modMove.SetLine(modMoveTo.Line)

        Dim direction = If(toIndex > fromIndex, 1, -1)
        For index = fromIndex + direction To toIndex Step direction
            Dim _mod = modsList.Item(index)
            _mod.Line -= direction
        Next

        If (direction > 0) Then toIndex += 1
        modsList.Insert(toIndex, modMove)

        If (direction < 0) Then fromIndex += 1
        modsList.RemoveAt(fromIndex)

        change = True
    End Sub

    Friend Sub ModSetState(index As Integer, state As CheckState)
        modsList.Item(index).State = state
        change = True
    End Sub

    Friend Sub AddMod(index As Integer, name As String)
        change = True

        Dim _mod As GMod = New GMod(name, CheckState.Checked)

        If (modsList.Count = 0) Then
            modsList.Add(_mod)
            modsContent = New List(Of String)()
            modsContent.Add(_mod.Name + "=1")

            modsIniFile = "\mods\mods_order.ini"
            change = True
            SaveModsList()
            Exit Sub
        End If

        If (index >= modsList.Count) Then
            _mod.Line = modsContent.Count
            modsList.Add(_mod)
            modsContent.Add(name + "=1")
            Exit Sub
        End If

        _mod.Line = modsList.Item(index).Line
        modsContent.Insert(_mod.Line, name + "=1")
        modsList.Insert(index, _mod)

        For n = index + 1 To modsList.Count - 1
            modsList.Item(n).Line += 1
        Next
    End Sub

    Friend Sub RemoveMod(index As Integer, name As String)
        If (modsList.Count > 0) Then
            Dim line = modsList(index).Line
            modsContent.RemoveAt(line)
            modsList.RemoveAt(index)

            For index = 0 To modsList.Count - 1
                If (modsList.Item(index).Line > line) Then
                    modsList.Item(index).Line -= 1
                End If
            Next

            modsIniFile = "\mods\mods_order.ini"
            change = True
            'SaveModsList()
        End If
    End Sub

End Module
